package com.itbaizhan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

@Controller
/*springMVC 控制器返回值可以为void String ModelAndView
 * 我们可以通过控制器方法的返回值设置跳转的视图*/
@RequestMapping(path = "/c2")
public class MyController2 {
      /*返回值为void  跳转不灵活，很小用
    此时会跳转到名字是 前缀+方法路径名+后缀 的jsp页面  访问路径名与jsp的页名相同
    在访问时加路径就可以，因为视图解析器加了前缀与后缀
    http://localhost:8080/hello*/
    @RequestMapping("/hello")
    public void helloMvc(){
        System.out.println("hello");
    }

    /*返回值为String
此时会跳转到名字是 前缀+返回值+后缀 的jsp页面    访问的地址是路径：
http://localhost:8080/c2/hello2*/
    @RequestMapping("/hello2")
    public String helloMvc2(){
        System.out.println("hello");
        ////方法执行后会跳转到/hello.jsp
        return "hello";
    }

    /*返回值为ModelAndView
这是SpringMVC提供的对象，该对象可以向request域设置数据并指定跳转的页面。
该对象中包含Model对象和View对象。
Model:向request域中设置数据  是Map键值对
View：指定跳转页面*/

    @RequestMapping("/hello3")
    public ModelAndView useMvc(){
        System.out.println("ModelAndView");
        //创建ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        //获取model对象，本质是一个map
        Map<String,Object> model = modelAndView.getModel();
        //使用model对象向request域设置数据
        model.put("name","百战");
        //使用view对象设置跳转的页面为/baizhan.jsp
        modelAndView.setViewName("baizhan");
        return modelAndView;
    }


    //当控制器返回值为ModelAndView时我们可以向request域设置数据，
    // 我们还有以下方法可以向request域设置数据：使用原生的HttpServletRequest   使用Model、ModelMap   使用Map集合
    @RequestMapping("hello4")
    public String setRequest(HttpServletRequest servletRequest){
        //key与value形式
        servletRequest.setAttribute("name","程序");
        //返回的页面
        return "baizhan";
    }

    /*SpringMVC提供了Model接口和ModelMap类，
控制器方法添加这两个类型的参数，使用该参数设置数据，
该数据就会存到request域中。*/
    @RequestMapping("/hello5")
    public String setRequestModel(Model model, ModelMap modelMap) {
        // 使用Model将数据存入request域
        model.addAttribute("name","学生");
        //modelMap.addAttribute("name","学校");
        return "baizhan";
    }

    /*Model接口底层就是一个Map集合，我们可以给控制器方法设置Map类型的参数，
    向Map中添加键值对，数据也会存到request域中。*/
    @RequestMapping("hello6")
    public String setRequest(Map map){
        //key与value形式
        map.put("name","程序");
        //返回的页面
        return "baizhan";
    }

    // Session作用域表示在当前会话中有效。
    // 在SpringMVC中对于Session作用域传值，
    // 只能使用HttpSession对象来实现。
    //一般是在用户登录页面后，在页面顶部存放的“你好xxx用户”，不论到哪个页面都可以看到“你好xxx用户”
    @RequestMapping("/hello7")
    public String setSession(HttpSession session){
        session.setAttribute("username","酒店");
        return "baizhan";
    }

    /*生命周期长，比较小用
    context作用域表示在整个应用范围都有效。
    在SpringMVC中对context作用域传值，
    只能使用ServletContext对象来实现。
    但是该对象不能直接注入到方法参数中，
    需要通过HttpSession对象获取。
    jsp页面中的applicationScope与java中的ServletContext相对应
    <h1>你好，${applicationScope.age}</h1>*/
    @RequestMapping("/hello8")
    public String setContext(HttpSession session){
        ServletContext servletContext = session.getServletContext();
        servletContext.setAttribute("age",22);
        return "baizhan";

    }

    //如果我们跳转时不想使用视图解析器，可以使用原生HttpServletRequest进行请求转发或HttpServletResponse进行重定向
    //使用原生的请求转发与重定向  直接用javaEE中的对象,没有使用视图解析器
    @RequestMapping("/hello9")
    public void myForward(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("name","我们");
        //请求转发   类上有@RequestMapping，地址也要写完整`
        request.getRequestDispatcher("/c2/hello10").forward(request,response);
        //重定向，/c2/hello10收不到name,地址改变
        //response.sendRedirect("/hello10");
    }
    @RequestMapping("/hello10")
    //从request域中取到数据
    public void myForward10(HttpServletRequest request){
        System.out.println("获取数据");
        System.out.println(request.getAttribute("name"));
    }

    //SpringMVC还提供了一种更简单的请求转发和重定向的写法
    @RequestMapping("/hello11")
    public String myForward3(HttpServletRequest request){
        request.setAttribute("name","孩子");
        return "redirect:/c2/hello10";
    }
}

/*SpringMVC默认情况下会在控制器执行完成后跳转到视图页面，
视图解析器能找到相应的视图，之前的404异常就是由于没有配置视图解析器导致找不到视图。

在SpringMVC中提供了13个视图解析器，用于支持不同的视图技术。
InternalResourceViewResolver是SpringMVC的默认视图解析器，
用来解析JSP视图。
在resources下的springmvc.xml配置
<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <!-- 视图前缀 -->
  <property name="prefix" value="/" />
  <!-- 视图后缀 -->
  <property name="suffix" value=".jsp" />
</bean>*/